<script setup lang="ts">
import { onMounted, ref } from 'vue'

const props = defineProps({
  color: {
    type: String,
    default: '#07f'
  }
})

const id = Math.random().toString().replace('.', '')

let width = ref(0)
let height = ref(0)

let resizeObserver
let elRef = ref()

const resize = () => {
  if (elRef.value) {
    let style = getComputedStyle(elRef.value)
    width.value = parseInt(style.getPropertyValue('width'))
    height.value = parseInt(style.getPropertyValue('height'))
  }
}

onMounted(() => {
  resizeObserver = new window.ResizeObserver((entries) => resize())
  resizeObserver.observe(elRef.value)
})
</script>

<template>
  <svg ref="elRef" class="border" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <path
        :id="`border-path-${id}`"
        fill="transparent"
        :d="`M0 0 h${width} v${height} h-${width} z`"
      ></path>
      <radialGradient :id="`border-gradient-${id}`" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="#fff" stop-opacity="1"></stop>
        <stop offset="100%" stop-color="#fff" stop-opacity="0"></stop>
      </radialGradient>
      <mask :id="`border-mask-${id}`">
        <circle cx="0" cy="0" r="50" :fill="`url(#border-gradient-${id})`">
          <animateMotion
            dur="5s"
            repeatCount="indefinite"
            :path="`M0 0 h${width} v${height} h-${width} z`"
            rotate="auto"
          ></animateMotion>
        </circle>
      </mask>
      <linearGradient :id="`Gradient-${id}`">
        <stop offset="0" stop-color="white" stop-opacity="0.5" />
        <stop offset="0.5" stop-color="white" stop-opacity="1" />
        <stop offset="1" stop-color="white" stop-opacity="0.5" />
      </linearGradient>
      <mask :id="`Mask-${id}`">
        <rect x="0" y="0" :width="width" :height="height" :fill="`url(#Gradient-${id})`" />
      </mask>
      <filter :id="`shadow-${id}`">
        <feDropShadow dx="0" dy="0" stdDeviation="5" flood-color="rgba(4, 175, 247, 0.5)" />
      </filter>
      <filter :id="`shadow-2-${id}`">
        <feDropShadow dx="0" dy="0" stdDeviation="50" flood-color="red" />
      </filter>
      <linearGradient :id="`Gradient-2-${id}`">
        <stop offset="0" stop-color="RGBA(0, 175, 246, 1)" stop-opacity="0" />
        <stop offset="0.5" stop-color="RGBA(0, 175, 246, 1)" stop-opacity="1" />
        <stop offset="1" stop-color="RGBA(0, 175, 246, 1)" stop-opacity="0" />
      </linearGradient>
    </defs>
    <use
      stroke-width="2"
      :href="`#border-path-${id}`"
      :stroke="color"
      :mask="`url(#Mask-${id})`"
      :style="`filter: url(#shadow-${id})`"
    ></use>
    <use
      stroke-width="2"
      :href="`#border-path-${id}`"
      :mask="`url(#border-mask-${id})`"
      stroke="#fff"
      :style="`filter: url(#shadow-2-${id})`"
    ></use>
  </svg>
</template>

<style scoped>
.border {
  pointer-events: none;
  width: 100%;
  height: 100%;
  position: absolute;
  inset: 0;
  z-index: 0;
}
</style>
